package com.eshop.eshopcache.controller;

import com.eshop.eshopcache.VO.ResultVO;
import com.eshop.eshopcache.model.ProductInfo;
import com.eshop.eshopcache.model.ShopInfo;
import com.eshop.eshopcache.prewarm.CachePrewarmThread;
import com.eshop.eshopcache.rebuild.RebuildCacheQueue;
import com.eshop.eshopcache.service.CacheService;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author: Xukai
 * @description:
 * @createDate: 2018/7/25 14:38
 * @modified By:
 */
@RestController
@Slf4j
public class CacheController {

    @Autowired
    private CacheService cacheService;

    @GetMapping("/getProductInfo")
    public ProductInfo getProductInfo(Long productId) {
        ProductInfo productInfo = null;
        // 先从redis中取数据
        try {
            productInfo = cacheService.getProductInfoFromRedisCache(productId);
            // TODO
            if (productInfo != null) {
                log.info("productInfo数据来自redis:{}" + productInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // redis取不到再从ehcache中取数据
        if (productInfo == null) {
            try {
                productInfo = cacheService.getProductInfoFromLocalCache(productId);
                // TODO
                if (productInfo != null) {
                    log.info("productInfo数据来自ehcache" + productInfo);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // ehcache取不到再从数据库取数据，同时主动更新数据缓存，但是异步的
        if (productInfo == null) {
            // 从远程商品服务数据库获得数据
            productInfo = cacheService.getProductInfoFromRemoteService(productId);
            // 将数据推送到一个内存队列中
            RebuildCacheQueue rebuildCacheQueue = RebuildCacheQueue.getInstance();
            rebuildCacheQueue.putInfo(productInfo);
        }
        return productInfo;
    }

    @GetMapping("/getShopInfo")
    public ShopInfo getShopInfo(Long shopId) {
        ShopInfo shopInfo = null;
        // 先从redis中取数据
        try {
            shopInfo = cacheService.getShopInfoFromRedisCache(shopId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // redis取不到再从ehcache中取数据
        if (shopInfo == null) {
            try {
                shopInfo = cacheService.getShopInfoFromLocalCache(shopId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // ehcache取不到再从数据库中取数据，同时主动更新数据缓存，但是异步的
        if (shopInfo == null) {
            // 从远程店铺服务数据库获得数据
            shopInfo = cacheService.getShopInfoFromRemoteService(shopId);
            // 将数据推送到一个内存队列中
            RebuildCacheQueue rebuildCacheQueue = RebuildCacheQueue.getInstance();
            rebuildCacheQueue.putInfo(shopInfo);
        }
        return shopInfo;
    }

    /**
     * 触发商品缓存预热服务
     *
     * @return
     */
    @GetMapping("/preWarmCache")
    public ResultVO preWarmCache() {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("PreWarmCache").build();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                1,
                1,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingDeque<>(),
                namedThreadFactory,
                new ThreadPoolExecutor.AbortPolicy());
        threadPoolExecutor.submit(new CachePrewarmThread());
        return ResultVO.success("成功触发");
    }
}
